#include "protocolNetwork.h"
#include "islotinterface.h"

double packetCount = 0;

protocol::protocol()
{
  this->_buffer = new char[4096];
}

protocol::~protocol() { }

void protocol::readEvent(Player *player)
{
  if (!player)  return ;
  
  if (player->getReadBuffer()->getReadSize() < sizeof(protocol::NetHeader)) return ;
  player->getReadBuffer()->extract(&_header, sizeof(protocol::NetHeader));  
  if (player->getReadBuffer()->getReadSize() < _header._len + sizeof(protocol::NetHeader)) return ;
  this->onReceivePacket(player);
}

void protocol::onReceivePacket(Player *player)
{
  unsigned int size = _header._len;
  if (size < 4096)
    {
      player->getReadBuffer()->extract(_buffer, size);
    }
  else
    {
      size = 4096;
      player->getReadBuffer()->extract(_buffer, size);
    }
  this->dispatchSlots(player, _buffer);
}

void protocol::dispatchSlots(Player *player, void *data)
{

  std::cout << _header._slotType <<  std::endl;
  
  if (this->_slotMap.find(static_cast<SlotType>(_header._slotType)) != this->_slotMap.end())
    {
      std::cout << "PROTOCOL::DISPATCH ; SLOTTYPE = " << _header._slotType << std::endl;
      this->_slotMap[static_cast<SlotType>(_header._slotType)]->onCall(player, player->getName(), data, _header._packetId, &_header);
    }
  else
    std::cout << "PROTOCOL::DISPATCH ; slot inconnu" << std::endl; 
}

void protocol::send(Player *player, SlotType type, std::string const &login, const char *data, unsigned int len)
{
  this->send(player, type, login, data, len, packetCount);
}

void protocol::send(Player *player, SlotType type, std::string const &login, const char *data, unsigned int len, unsigned int id)
{
  protocol::NetPacket packet;

  ::memset(&packet, 0, sizeof(protocol::NetPacket));
  packet._header._slotType = type;
  packet._header._packetId = id;
  packet._header._len = len;
  strcpy(packet.data, (char *) data); 
  player->getWriteBuffer()->append(&packet, sizeof(protocol::NetPacket));
}

void protocol::sendPacket(Player *player)
{
  protocol::NetPacket packet;
  ::memset(&packet, 0, sizeof(protocol::NetPacket));
  packet._header._slotType = PLAYER_PSEUDO;
  packet._header._packetId = packetCount;
  packet._header._len = 0;
  //  packet.data = 0;
  player->getWriteBuffer()->append(&packet, sizeof(protocol::NetPacket));
}

void protocol::registerSlot(SlotType id, ISlotInterface *slot)
{
  this->_slotMap[id] = slot;
}
